﻿using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Padsurface.CoreAudio.Components.MMDevice;
using Padsurface.CoreAudio.Components.MMDevice.Interfaces;
using Padsurface.Tests;
using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace Padsurface.CoreAudio.Tests.Unit.Components.ActivateAudioInterfaceCompletionHandlerSpecifications
{
    public abstract class WhenActivateCompleted : TestBase
    {
        protected IActivateAudioInterfaceCompletionHandler ActivateAudioInterfaceCompletionHandler { get; set; }
        protected IActivateAudioInterfaceAsyncOperation ActivateOperation { get; set; }
        public object ActivatedInterface { get; set; }

        protected override void Arrange()
        {
            EventTrigger = new ManualResetEvent(false);

            ActivateAudioInterfaceCompletionHandler = new ActivateAudioInterfaceCompletionHandler();
            ActivateAudioInterfaceCompletionHandler.InterfaceActivated += OnInterfaceActivated;

            ActivateOperation = new ActivateAudioInterfaceAsyncOperationStub(0);
        }

        private void OnInterfaceActivated(object sender, InterfaceActivatedEventArgs e)
        {
            Exception = e.Exception;
            ActivatedInterface = e.ActivatedInterface;

            EventTrigger.Set();
        }

        protected override void Act()
        {
            ActivateAudioInterfaceCompletionHandler.ActivateCompleted(ActivateOperation);
        }
    }

    [TestClass]
    public class WhenActivateCompletedGivenActivateOperationIsNull : WhenActivateCompleted
    {
        protected override void Arrange()
        {
            base.Arrange();
            ActivateOperation = null;
        }

        [TestMethod]
        public void ThenEventArgsShouldContainAnArgumentNullException()
        {
            Assert.IsNotNull(Exception);
            Assert.IsInstanceOfType(Exception, typeof(ArgumentNullException));
            Assert.AreEqual("activateOperation", (Exception as ArgumentNullException).ParamName);
        }
    }

    [TestClass]
    public class WhenActivateCompletedGivenGetActivateResultThrowsException : WhenActivateCompleted
    {
        protected override void Arrange()
        {
            base.Arrange();
            uint E_ILLEGAL_METHOD_CALL = 0x8000000E;
            ActivateOperation = new ActivateAudioInterfaceAsyncOperationStub((int)E_ILLEGAL_METHOD_CALL);
        }

        [TestMethod]
        public void ThenEventArgsShouldContainAComException()
        {
            Assert.IsNotNull(Exception);
            Assert.IsInstanceOfType(Exception, typeof(COMException));
        }
    }
}
